import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from "@angular/forms"
import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
import * as moment from "moment"

import { DepartmentManageService } from "./department-manage.service"
import { HCommonService } from 'src/app/h-common/h-common.service';

@Component({
    selector: 'app-department-manage',
    templateUrl: './department-manage.component.html',
    styleUrls: ['./department-manage.component.scss']
})
export class DepartmentManageComponent implements OnInit {

    searchKey = <string>"";
    dateRange = [];
    status = <any>"";     // 1  => 正常     2  =>  禁用
    listOfMapData = <any>[];
    sourceDataBackUp = [];
    hztreeData = [];
    htreeValue: string;
    isShowModal = <boolean>false;
    isOkLoading = <boolean>false;
    departmentForm: FormGroup;
    departmentStatus = <string>"true";
    departmentName = <string>""
    private deleteIds: number[] = [];
    private editId: number = -1;
    mapOfCheckedId: { [key: string]: boolean } = {};
    isAllCheck = <boolean>false;
    isIndeterminate = <boolean>false;
    mapOfExpandedData = [];
    copyData = [];
    bornRole = {};

    modalDomBox : any

    constructor(
        private departmentManageService: DepartmentManageService,
        private fb: FormBuilder,
        private modal: NzModalService,
        private commonService : HCommonService
    ) { }

    async ngOnInit() {
        this.modalDomBox = document.querySelector("#modal_box");
        /* 获取权限 */
        this.bornRole = this.commonService.getRoles("dept");

        this.departmentForm = this.fb.group({
            departmentName: [null, [Validators.required]],
            departmentStatus: [true],
            pid: [0]
        })
        await this.getList();
        this.initMapOfExpandedData();
    }

    collapse(array, data, $event: boolean): void {
        if ($event === false) {
            if (data.children) {
                data.children.forEach(d => {
                    const target = array.find(a => a.id === d.id);
                    target.expand = false;
                    this.collapse(array, target, false);
                });
            } else {
                return;
            }
        }
    }
    convertTreeToList(root) {
        const stack = [];
        const array = [];
        const hashMap = {};
        stack.push({ ...root, level: 0, expand: false });

        while (stack.length !== 0) {
            const node = stack.pop()!;
            this.visitNode(node, hashMap, array);
            if (node.children) {
                for (let i = node.children.length - 1; i >= 0; i--) {
                    stack.push({ ...node.children[i], level: node.level! + 1, expand: false, parent: node });
                }
            }
        }
        return array;
    }
    visitNode(node, hashMap, array): void {
        if (!hashMap[node.id]) {
            hashMap[node.id] = true;
            array.push(node);
        }
    }
    initMapOfExpandedData() {
        this.listOfMapData.forEach(item => {
            this.mapOfExpandedData[item.id] = this.convertTreeToList(item);
        });
    }

    checkAll(value: boolean): void {
        this.deleteIds = [];
        this.mapOfExpandedData.forEach(item => {
            if (item) {
                item.forEach($item => {
                    this.mapOfCheckedId[$item.id] = value
                })
            }
        });
        this.filterDelData();
        this.isIndeterminate = false;
    }
    checkItem(item, id, pid) {
        this.mapOfCheckedId[item.id] = this.mapOfCheckedId[id];
        if (item.children && item.children.length != 0) {
            for (let i = 0; i < item.children.length; i++) {
                this.checkItem(item.children[i], id, pid);
            }
        }
        let _temp = [];
        this.mapOfExpandedData.forEach(item => {
            item.forEach($item => {
                if ($item.pid == pid) {
                    _temp.push($item)
                }
            });
        });
        let _isChecked = true;
        _temp.forEach(item => {
            for (const key in this.mapOfCheckedId) {
                if (!this.mapOfCheckedId[item.id]) {
                    _isChecked = false;
                }
            }
        });
        this.mapOfCheckedId[pid] = _isChecked;

        // this.isAllCheck = this.mapOfCheckedId[1];
        this.isAllCheck = this.listOfMapData.every(item=>{
            return this.mapOfCheckedId[item.id]
        })
        this.isIndeterminate = this.listOfMapData.some(item=>{
            return this.mapOfCheckedId[item.id] && !this.isAllCheck
        })
        this.filterDelData();
    }

    handleShowModal(item?): void {
        this.isShowModal = true;

        this.departmentForm.reset({
            departmentStatus: true
        })
        if (item) {

            if( item === 2 ){
                _(this.listOfMapData, this.deleteIds[0], (data)=>{
                    item = data
                });
            }

            this.editId = item.id;
            this.departmentForm.patchValue({
                departmentName: item.name,
                departmentStatus: item.enabled,
                pid: item.pid
            })

            this.copyData = [];
            this.copyListData(this.listOfMapData, this.copyData);
            let editHtreeData = this.filterListData(this.copyData, item.id);
            this.initHtree(editHtreeData);
        } else {
            this.editId = -1;
            this.initHtree(this.listOfMapData);

        }

        function _(data, id, fn){
            let _item
            if( data.length > 0 ){
                for(let i =0; i<data.length; i++){
                    if( data[i].id === id ){
                        fn && fn(data[i])
                        return false;
                    }else{
                        if( data[i].children ){
                            _(data[i].children, id, fn)
                        }
                    }
                };
            }
            return _item;
        }
    }
    handleSubmit(): void {
        if (this.editId !== -1) {
            this.edit();
        } else {
            this.add();
        }
    }
    handleCancel(): void {
        this.isShowModal = false;
        this.isOkLoading = false;
    }
    async handleSearch() {
        await this.getList();
        this.initMapOfExpandedData();
    }
    handleDate(ev) {
        this.dateRange = ev.map(item => {
            return moment(item).format("YYYY-MM-DD") + " 00:00:00"
        })
        this.getList();
    }
    handleStatus(ev) {
        this.getList();
    }
    handleSwitch(data) {
        let _dataJson = {
            enabled: data.enabled,
            id: data.id,
            name: data.name,
            pid: data.pid
        }
        this.editSubmitFn(_dataJson);
    }
    filterDelData() {
        this.deleteIds = [];
        for (const key in this.mapOfCheckedId) {
            if (this.mapOfCheckedId[key]) {
                this.deleteIds.push(Number(key))
            }
        }
    }
    handleDelete() {
        this.modal.confirm({
            nzTitle: "删除提示",
            nzContent: "确定要删除这条数据吗？",
            nzOnOk: () => {
                this.delete(this.deleteIds);
            }
        })
    }
    handleHtree(ev) {

    }
    initHtree(data) {
        const _tempArr = data;
        if (_tempArr.length != 0) {
            for (let i = 0; i < _tempArr.length; i++) {
                let _item = _tempArr[i];
                _item.title = _item.name;
                _item.key = _item.id
                if (_item.children) {
                    this.initHtree(_item.children)
                }
            }
        }
        this.hztreeData = _tempArr;
    }
    filterListData(sourceData, depId: number) {
        const _tempArr = sourceData;
        if (_tempArr.length != 0) {
            for (let i = 0; i < _tempArr.length; i++) {
                if (_tempArr[i].id === depId) {
                    _tempArr.splice(i, 1);
                } else {
                    if (_tempArr[i].children) {
                        this.filterListData(_tempArr[i].children, depId)
                    }
                }
            }
        }
        return _tempArr
    }
    copyListData(sourceData, copyData) {
        if (sourceData.length != 0) {
            for (let i = 0; i < sourceData.length; i++) {
                copyData[i] = { ...sourceData[i] };
                copyData[i].children = [];
                if (sourceData[i].children) {
                    this.copyListData(sourceData[i].children, copyData[i].children)
                }
            }
        }
    }

    getList() {
        return new Promise((resolve, reject) => {
            try {
                let _dataJson = {
                    createTime: this.dateRange,
                    enabled: this.status,
                    name: this.searchKey
                }
                this.departmentManageService.apiList(_dataJson).subscribe(res => {
                    this.listOfMapData = [...res.content];
                    this.initHtree(this.listOfMapData);
                    resolve()
                })
            } catch (e) {
                reject(e)
            }
        })
    }
    edit() {
        for (const i in this.departmentForm.controls) {
            this.departmentForm.controls[i].markAsDirty();
            this.departmentForm.controls[i].updateValueAndValidity();
        }
        if (this.departmentForm.status == "VALID") {
            this.isOkLoading = true;
            let _value = this.departmentForm.value;
            let _dataJson = {
                enabled: _value.departmentStatus,
                name: _value.departmentName,
                pid: _value.pid,
                id: this.editId
            }
            this.editSubmitFn(_dataJson)
        }
    }
    editSubmitFn(data) {
        this.departmentManageService.apiEdit(data).subscribe(async res => {
            await this.getList();
            this.initMapOfExpandedData();
            this.hztreeData = []
            this.initHtree(this.listOfMapData);
            this.handleCancel();
        }, data => {
            this.isOkLoading = false;
        })
    }
    add() {
        for (const i in this.departmentForm.controls) {
            this.departmentForm.controls[i].markAsDirty();
            this.departmentForm.controls[i].updateValueAndValidity();
        }
        if (this.departmentForm.status == "VALID") {
            this.isOkLoading = true;
            let _value = this.departmentForm.value;
            let _dataJson = {
                enabled: _value.departmentStatus,
                name: _value.departmentName,
                pid: _value.pid
            }
            this.departmentManageService.apiAdd(_dataJson).subscribe(async res => {
                await this.getList();
                this.initMapOfExpandedData();
                this.handleCancel();
            }, data => {
                this.isOkLoading = false;
            })
        }
    }
    delete(ids) {
        this.departmentManageService.apiDelete(ids).subscribe(async res => {
            await this.getList();
            this.initMapOfExpandedData();
            this.handleCancel();
            this.deleteIds = []
        })
    }
}
